package com.lut.reservation.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lut.reservation.bean.ReservationLine;
import com.lut.reservation.bean.Room;
import com.lut.reservation.bean.RoomReservation;
import com.lut.reservation.bean.User;
import com.lut.reservation.dao.RoomReservationDao;
import com.lut.reservation.exception.BusinessException;
import com.lut.reservation.service.ReservationLineService;
import com.lut.reservation.service.RoomReservationService;
import com.lut.reservation.service.RoomService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.Optional;

/**
 * @author zyt
 */
@Slf4j
@Service
public class RoomReservationServiceImpl extends ServiceImpl<RoomReservationDao, RoomReservation> implements RoomReservationService {

  @Autowired
  private RoomService roomService;

  @Autowired
  private ReservationLineService lineService;

  @Autowired
  private HttpSession session;

  @Override
  public boolean save(RoomReservation entity) {
    if (entity.getStartTime().before(new Date())) {
      throw new BusinessException("开始时间不得小于当前时间");
    }
    final Room room = roomService.getById(entity.getRoomId());
    final Object bean = session.getAttribute("user");
    if (bean == null) {
      throw new BusinessException("请先登录！");
    }
    User user = (User) bean;
    entity.setUserName(user.getName());
    entity.setUserId(user.getId());
    entity.setState("INIT");
    entity.setRoomNumber(room.getRoomNumber());
    Optional<RoomReservation> one = this.lambdaQuery()
        .or(i -> {
          i.between(RoomReservation::getStartTime, entity.getStartTime(), entity.getEndTime());
          i.or();
          i.between(RoomReservation::getEndTime, entity.getStartTime(), entity.getEndTime());
        })
        .ne(RoomReservation::getState, "REFUSE")
        .oneOpt();
    if (one.isPresent()) {
      throw new BusinessException("该时间已经被预约了！");
    }
    final boolean save = super.save(entity);
    lineService.save(buildLine(entity.getId(), entity.getState()));
    return save;
  }

  @Override
  public void updateState(Integer id, String state) {
    check(id, state);
    this.lambdaUpdate()
        .set(RoomReservation::getState, state)
        .eq(RoomReservation::getId, id)
        .update();
    lineService.save(buildLine(id, state));
  }

  private void check(Integer id, String finish) {
    final RoomReservation reservation = getById(id);
    if ("INIT".equals(reservation.getState())) {
      if (!("PASS".equals(finish) || "REFUSE".equals(finish))) {
        throw new BusinessException("该预定不需要处理，请刷新后重试！");
      }
    }
    if ("CANCEL".equals(reservation.getState())) {
      if (!("APPROVE".equals(finish) || "REJECT".equals(finish))) {
        throw new BusinessException("该预定不需要处理，请刷新后重试！");
      }
    }
    if ("PASS".equals(reservation.getState())) {
      if (!("COMMENT".equals(finish) || "CANCEL".equals(finish))) {
        throw new BusinessException("该预定不需要处理，请刷新后重试！");
      }
    }
  }

  private ReservationLine buildLine(Integer id, String state) {
    final ReservationLine reservationLine = new ReservationLine();
    final Object bean = session.getAttribute("user");
    if (bean != null) {
      User user = (User) bean;
      reservationLine.setUserId(user.getId());
      reservationLine.setUserName(user.getName());
    }
    reservationLine.setReservationId(id);
    reservationLine.setAction(state);
    reservationLine.setNewState(state);
    reservationLine.setActionTime(new Date());
    return reservationLine;
  }
}
